// internal/apps/auth/repositories/role_repository.go
package repositories

import (
	"star-go-app/internal/apps/auth/models"
	"star-go-app/internal/apps/auth/serializers"
	"star-go-app/pkg/infra/database"

	"gorm.io/gorm"
)

// RoleRepository 角色仓储接口
type RoleRepository interface {
	// 基本CRUD操作
	CreateRole(role *models.Role) error
	GetRoleByID(id uint) (*models.Role, error)
	GetRoleByCode(code string) (*models.Role, error)
	UpdateRole(role *models.Role) error
	DeleteRole(id uint) error

	// 列表查询
	GetRoleList(req *serializers.RoleListRequest) ([]*models.Role, int64, error)

	// 检查操作
	IsRoleCodeExists(code string, excludeID ...uint) (bool, error)
	IsRoleNameExists(name string, excludeID ...uint) (bool, error)

	// 永久删除角色
	DeleteRolePermanently(id uint) error
}

// roleRepository 角色仓储实现
type roleRepository struct {
	db *gorm.DB
}

// NewRoleRepository 创建角色仓储实例
func NewRoleRepository() RoleRepository {
	return &roleRepository{
		db: database.GetDB(),
	}
}

// CreateRole 创建角色
func (r *roleRepository) CreateRole(role *models.Role) error {
	return r.db.Create(role).Error
}

// GetRoleByID 根据ID获取角色
func (r *roleRepository) GetRoleByID(id uint) (*models.Role, error) {
	var role models.Role
	err := r.db.Where("id = ?", id).First(&role).Error
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// GetRoleByCode 根据编码获取角色
func (r *roleRepository) GetRoleByCode(code string) (*models.Role, error) {
	var role models.Role
	err := r.db.Where("code = ?", code).First(&role).Error
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// UpdateRole 更新角色
func (r *roleRepository) UpdateRole(role *models.Role) error {
	return r.db.Save(role).Error
}

// DeleteRole 删除角色
func (r *roleRepository) DeleteRole(id uint) error {
	return r.db.Delete(&models.Role{}, id).Error
}

// GetRoleList 获取角色列表
func (r *roleRepository) GetRoleList(req *serializers.RoleListRequest) ([]*models.Role, int64, error) {
	var roles []*models.Role
	var total int64

	// 构建查询条件
	query := r.db.Model(&models.Role{})

	// 添加搜索条件
	if req.Name != "" {
		query = query.Where("name LIKE ?", "%"+req.Name+"%")
	}
	if req.Code != "" {
		query = query.Where("code LIKE ?", "%"+req.Code+"%")
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(offset).Limit(req.PageSize).Order("created_at DESC").Find(&roles).Error; err != nil {
		return nil, 0, err
	}

	return roles, total, nil
}

// IsRoleCodeExists 检查角色编码是否存在
func (r *roleRepository) IsRoleCodeExists(code string, excludeID ...uint) (bool, error) {
	query := r.db.Model(&models.Role{}).Where("code = ?", code)

	// 排除指定ID（用于更新时检查）
	if len(excludeID) > 0 {
		query = query.Where("id != ?", excludeID[0])
	}

	var count int64
	err := query.Count(&count).Error
	return count > 0, err
}

// IsRoleNameExists 检查角色名称是否存在
func (r *roleRepository) IsRoleNameExists(name string, excludeID ...uint) (bool, error) {
	query := r.db.Model(&models.Role{}).Where("name = ?", name)

	// 排除指定ID（用于更新时检查）
	if len(excludeID) > 0 {
		query = query.Where("id != ?", excludeID[0])
	}

	var count int64
	err := query.Count(&count).Error
	return count > 0, err
}

// DeleteRolePermanently 永久删除角色
func (r *roleRepository) DeleteRolePermanently(id uint) error {
	return r.db.Unscoped().Delete(&models.Role{}, id).Error
}
